//
// Created by casdon on 2024/9/2.
//

#ifndef CIOT_CSDK_CIOT_MOBILE_H
#define CIOT_CSDK_CIOT_MOBILE_H


#include "types.h"

#ifdef __cplusplus
extern "C" {
#endif

#if CIOT_SDK_FOR_MOBILE

typedef enum Ciot_clink_request_type_e {
    Ciot_Clink_Request_BLE = 0,         // BLE
    Ciot_Clink_Request_AP = 1,        // AP
    Ciot_Clink_Request_MAX
} Ciot_clink_request_type;              // Ciot 基础返回状态

/**
 * 开始配网扫描
 */
CIOT_API
typedef Ciot_res (*ciot_mobile_start_discover) ( int timeout_ms );

/**
 * 发起配网请求
 */
CIOT_API
typedef Ciot_res (*ciot_mobile_clink_request) ( const char * uid, const char * mac ,Ciot_clink_request_type type);

CIOT_ADAPTER
typedef const char * (*ciot_mobile_get_app_deviceID) (void);

CIOT_ADAPTER
typedef const char * (*ciot_mobile_get_app_userID) (void);

CIOT_ADAPTER
typedef const char * (*ciot_mobile_get_wifi_ssid) (void);

CIOT_ADAPTER
typedef const char * (*ciot_mobile_get_wifi_pass) (void);

/**
    本方法 会传入一个 "Casdon" 用于名称检索
    另一个UUID为凯度专用配网服务ID 可用于精准识别凯度产品
**/
CIOT_ADAPTER
typedef Ciot_res (*ciot_mobile_ble_scan_device) ( const char * name, const char * serviceUUID );

CIOT_ADAPTER
typedef Ciot_res (*ciot_mobile_ap_scan_device) ( const char * name);

CIOT_ADAPTER
typedef Ciot_res (*ciot_mobile_ap_udp_client_connect) ( int port);

CIOT_ADAPTER
typedef Ciot_res (*ciot_mobile_ap_tcp_client_connect) ( const char * ip, int port);

/**
 * 通知SDK 搜索到蓝牙设备
 * uuid, mac 至少提供一个
 * scanRspData scanRspDataLen 不能为空 不能为0
 */
CIOT_EVENT
typedef Ciot_res (*ciot_mobile_ble_scan_result_handler) ( const char * uuid, const char * mac, const uint8_t * scanRspData, size_t scanRspDataLen );

/**
 * 设备 被发现 SDK通知应用层 (uid,mac至少会提供一个)
 * @uid 唯一ID
 * @mac mac地址
 * @pid 产品ID/SN8
 * @isBLE 是否是蓝牙设备
 * @clinStatus 配网状态（0表示未配网）
 */
CIOT_NOTIFY
typedef Ciot_res (*ciot_mobile_ble_discovered_notify) ( const char * uid, const char * mac, const char * pid, Ciot_clink_connection_status clinkStatus, int random );
CIOT_NOTIFY
typedef Ciot_res (*ciot_mobile_ap_discovered_notify) ( const char * name, const char * pid,  Ciot_clink_connection_status clinkStatus, bool encrypted, const char * passwd,int random );

/**
 * 设定MTU
 */
CIOT_ADAPTER
typedef Ciot_res (*ciot_mobile_ble_set_mtu_request) ( int mtu );

/**
 * 设定读写 Char
 */
CIOT_ADAPTER
typedef Ciot_res (*ciot_mobile_ble_set_rw_char) ( const char * readChar, const char * writeChar );

/**
 * 进行蓝牙设备连接 uid,mac 2选一
 * @uid
 * @mac
 */
CIOT_ADAPTER
typedef Ciot_res (*ciot_mobile_ble_connect) (const char * uid, const char * mac);

CIOT_EVENT
typedef Ciot_res (*ciot_mobile_ble_connected) (const char * uid, const char * mac);

CIOT_EVENT
typedef Ciot_res (*ciot_mobile_ble_disconnected) (const char * uid, const char * mac);

CIOT_EVENT
typedef Ciot_res (*ciot_mobile_ble_wr_ready) (void);

/**
 * 发送数据
 */
CIOT_ADAPTER
typedef Ciot_res (*ciot_mobile_ble_message_send) ( const uint8_t * data, size_t len );

/**
 * 通知SDK 收到蓝牙数据
 * RAW数据直接回传
 */
CIOT_EVENT
typedef Ciot_res (*ciot_mobile_ble_message_received) ( const uint8_t * data, size_t len );

CIOT_NOTIFY
typedef Ciot_res (*ciot_mobile_clink_event_notify) ( Ciot_clink_connection_status e_enum, const char * event, const char * message );

CIOT_NOTIFY
typedef Ciot_res (*ciot_mobile_device_id_received) ( const char * deviceID );

CIOT_EVENT
typedef Ciot_res (*ciot_mobile_ap_connected) (const char * ssid, const char * pass);
CIOT_EVENT
typedef Ciot_res (*ciot_mobile_ap_disconnected) (const char * uid, const char * mac);
CIOT_EVENT
typedef Ciot_res (*ciot_mobile_ap_scan_result_handler) ( const char * ssid, bool encrypted );
CIOT_EVENT
typedef Ciot_res (*ciot_mobile_ap_udp_message_received) ( const uint8_t * data, size_t len );
CIOT_EVENT
typedef Ciot_res (*ciot_mobile_ap_tcp_connected) ( const char * ip, int port );
CIOT_EVENT
typedef Ciot_res (*ciot_mobile_ap_tcp_disconnected) ( const char * ip, int port );
CIOT_EVENT
typedef Ciot_res (*ciot_mobile_ap_tcp_message_received) ( const uint8_t * data, size_t len );
CIOT_ADAPTER
typedef Ciot_res (*ciot_mobile_ap_connect) (const char * ssid, const char * pass);
CIOT_ADAPTER
typedef Ciot_res (*ciot_mobile_ap_tcp_message_send) ( const uint8_t * data, size_t len );

typedef struct ciot_mobile_adapter_manager_t
{

    CIOT_NOTIFY
    ciot_mobile_ble_discovered_notify ble_discovered;

    CIOT_NOTIFY
    ciot_mobile_ap_discovered_notify ap_discovered;

    CIOT_NOTIFY
    ciot_mobile_clink_event_notify  clink_event_notify;

    CIOT_NOTIFY
    ciot_mobile_device_id_received  did_received;

    CIOT_ADAPTER
    ciot_mobile_get_app_deviceID  get_app_deviceID;

    CIOT_ADAPTER
    ciot_mobile_get_app_userID  get_app_userID;

    CIOT_ADAPTER
    ciot_mobile_get_wifi_ssid   get_wifi_ssid;

    CIOT_ADAPTER
    ciot_mobile_get_wifi_pass   get_wifi_pass;

    CIOT_ADAPTER
    ciot_mobile_ble_scan_device ble_scan_device;

    CIOT_ADAPTER
    ciot_mobile_ble_message_send ble_message_send;

    CIOT_ADAPTER
    ciot_mobile_ble_set_mtu_request ble_set_mtu_request;

    CIOT_ADAPTER
    ciot_mobile_ble_set_rw_char ble_set_rw_char;


    CIOT_EVENT
    ciot_mobile_ble_scan_result_handler ble_scan_result_handler;

    CIOT_EVENT
    ciot_mobile_ble_message_received ble_message_received;

    CIOT_EVENT
    ciot_mobile_ble_connected ble_connected;

    CIOT_EVENT
    ciot_mobile_ble_disconnected ble_disconnected;

    CIOT_ADAPTER
    ciot_mobile_ble_connect ble_connect;

    CIOT_API
    ciot_mobile_clink_request clink_request;

    CIOT_API
    ciot_mobile_start_discover start_discover; // timeout in ms

    CIOT_EVENT
    ciot_mobile_ble_wr_ready ble_wr_ready; // 读写接口准备完毕

    CIOT_EVENT
    ciot_mobile_ap_connected ap_connected;

    CIOT_EVENT
    ciot_mobile_ap_disconnected ap_disconnected;

    CIOT_EVENT
    ciot_mobile_ap_scan_result_handler ap_scan_result_handler;

    CIOT_EVENT
    ciot_mobile_ap_udp_message_received ap_udp_message_received;

    CIOT_EVENT
    ciot_mobile_ap_tcp_connected ap_tcp_connected;

    CIOT_EVENT
    ciot_mobile_ap_tcp_disconnected ap_tcp_disconnected;

    CIOT_EVENT
    ciot_mobile_ap_tcp_message_received ap_tcp_message_received;

    CIOT_ADAPTER
    ciot_mobile_ap_connect ap_connect;
    CIOT_ADAPTER
    ciot_mobile_ap_scan_device ap_scan_device;
    CIOT_ADAPTER
    ciot_mobile_ap_udp_client_connect ap_udp_client_connect;
    CIOT_ADAPTER
    ciot_mobile_ap_tcp_client_connect ap_tcp_client_connect;
    CIOT_ADAPTER
    ciot_mobile_ap_tcp_message_send ap_tcp_message_send;

} ciot_mobile_adapter_manager;

/**
 * 适配器初始化 返回一个对象
 * @return
 */
const ciot_mobile_adapter_manager * ciot_mobile_adapter_manager_init();
const ciot_mobile_adapter_manager * ciot_mobile_adapter_manager_standalone();

#define ciot_mobile() ciot_mobile_adapter_manager_standalone()

CIOT_API
const char * ciot_mobile_sign_mqtt_pass( char* pid, char * did );

/**
 * 适配器注册
 * @param adapterManager
 * @param notifyDeviceDiscovered
 * @param adapter_ble_scan
 * @param adapter_ble_send
 * @param adapter_ble_set_mtu_req
 * @return
 */
Ciot_res ciot_mobile_adapter_manager_reg(

        CIOT_ADAPTER
        ciot_mobile_get_app_deviceID            get_app_deviceID,
        ciot_mobile_get_app_userID              get_app_userID,

        ciot_mobile_ble_scan_device             adapter_ble_scan,
        ciot_mobile_ble_connect                 adapter_ble_connect,
        ciot_mobile_ble_set_mtu_request         adapter_ble_set_mtu_req,
        ciot_mobile_ble_set_rw_char             adapter_ble_set_rw_char,
        ciot_mobile_ble_message_send            adapter_ble_send,
  
        ciot_mobile_ap_scan_device              adapter_ap_scan,
        ciot_mobile_ap_connect                  adapter_ap_connect,
        CIOT_NOTIFY
        ciot_mobile_ap_discovered_notify        notify_ap_discovered,
        ciot_mobile_ap_udp_client_connect       adapter_ap_udp_client_connect,
        ciot_mobile_ap_tcp_client_connect       adapter_ap_tcp_client_connect,
        ciot_mobile_ap_tcp_message_send        adapter_ap_tcp_message_send,

        ciot_mobile_get_wifi_ssid               adapter_get_wifi_ssid,
        ciot_mobile_get_wifi_pass               adapter_get_wifi_pass,

        CIOT_NOTIFY
        ciot_mobile_ble_discovered_notify    notify_device_discovered,

        CIOT_NOTIFY
        ciot_mobile_device_id_received          notify_received_deviceID,

        CIOT_NOTIFY
        ciot_mobile_clink_event_notify          notify_clink_event
);

#if CIOT_SDK_FOR_JAVA

CIOT_NOTIFY
Ciot_res ciot_mobile_device_helloJava_jni();

CIOT_NOTIFY
Ciot_res ciot_mobile_device_test_input_bytes_jni( const char * data, int len );

CIOT_NOTIFY
Ciot_res ciot_mobile_ble_discovered_notify_jni( const char * uid, const char * mac, const char * pid, Ciot_clink_connection_status clinkStatus,int random );

CIOT_NOTIFY
Ciot_res ciot_mobile_clink_event_notify_jni(Ciot_clink_connection_status e_enum, const char * event, const char * message );

CIOT_NOTIFY
Ciot_res ciot_mobile_device_id_received_jni( const char * deviceID );

CIOT_NOTIFY 
Ciot_res ciot_mobile_ap_discovered_notify_jni( const char * ssid, const char * pid,  Ciot_clink_connection_status clinkStatus, bool encrypted, const char * passwd ,int random);

CIOT_ADAPTER
const char * ciot_mobile_get_app_deviceID_jni(void);

CIOT_ADAPTER
const char * ciot_mobile_get_app_userID_jni(void);

CIOT_ADAPTER
const char * ciot_mobile_get_wifi_ssid_jni(void);

CIOT_ADAPTER
const char * ciot_mobile_get_wifi_pass_jni(void);

CIOT_ADAPTER
Ciot_res ciot_mobile_ble_scan_device_jni( const char * name, const char * serviceUUID );

CIOT_ADAPTER
Ciot_res ciot_mobile_ble_connect_jni(const char * uid, const char * mac);

CIOT_ADAPTER
Ciot_res ciot_mobile_ble_set_mtu_request_jni( int mtu );

CIOT_ADAPTER
Ciot_res ciot_mobile_ble_set_rw_char_jni( const char * readChar, const char * writeChar );

CIOT_ADAPTER
Ciot_res ciot_mobile_ble_message_send_jni( const uint8_t * data, size_t len );


Ciot_res ciot_mobile_adapter_manager_reg_jni();

Ciot_res ciot_mobile_ap_scan_device_jni( const char * name);

Ciot_res ciot_mobile_ap_connect_jni(const char * ssid, const char * pass);

Ciot_res ciot_mobile_udp_client_jni(int port);

Ciot_res ciot_mobile_tcp_client_jni(const char * ip, int port);
CIOT_ADAPTER
Ciot_res ciot_mobile_ap_tcp_message_send_jni( const uint8_t * data, size_t len );
#endif

#endif

#ifdef __cplusplus
}
#endif


#endif //CIOT_CSDK_CIOT_MOBILE_H